from typing import List, Optional
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete, and_

from app.db.postgres import get_session
from app.models import UserAccount, UserRole, Role
from app.schemas.user import UserCreate, UserRead, UserRoleSet, UserUpdate
from app.schemas.role import RoleRead
from app.core.security import get_password_hash, get_current_user


router = APIRouter(prefix="/users", tags=["users"])


@router.get("", response_model=List[UserRead])
async def list_users(
    username: Optional[str] = None,
    full_name: Optional[str] = None,
    email: Optional[str] = None,
    enabled: Optional[bool] = None,
    session: AsyncSession = Depends(get_session),
    current_user: UserAccount = Depends(get_current_user),
):
    query = select(UserAccount)
    conds = []
    if username:
        conds.append(UserAccount.username.ilike(f"%{username}%"))
    if full_name:
        conds.append(UserAccount.full_name.ilike(f"%{full_name}%"))
    if email:
        conds.append(UserAccount.email.ilike(f"%{email}%"))
    if enabled is not None:
        conds.append(UserAccount.enabled == enabled)
    if conds:
        query = query.where(and_(*conds))
    result = await session.execute(query)
    users = result.scalars().all()
    return [UserRead(id=u.id, username=u.username, full_name=u.full_name, email=u.email, enabled=u.enabled) for u in users]


@router.post("", response_model=UserRead)
async def create_user(payload: UserCreate, session: AsyncSession = Depends(get_session), current_user: UserAccount = Depends(get_current_user)):
    # 检查用户名重复
    exists = await session.execute(select(UserAccount).where(UserAccount.username == payload.username))
    if exists.scalar_one_or_none() is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")
    user = UserAccount(
        username=payload.username,
        password_hash=get_password_hash(payload.password),
        full_name=payload.full_name,
        email=payload.email,
        enabled=payload.enabled,
    )
    session.add(user)
    await session.flush()
    await session.refresh(user)
    await session.commit()
    return UserRead(id=user.id, username=user.username, full_name=user.full_name, email=user.email, enabled=user.enabled)


@router.post("/{user_id}/roles")
async def set_user_roles(user_id: UUID, payload: UserRoleSet, session: AsyncSession = Depends(get_session), current_user: UserAccount = Depends(get_current_user)):
    # 清空旧关系
    await session.execute(delete(UserRole).where(UserRole.user_id == user_id))
    # 验证角色存在并建立新关系
    if payload.role_ids:
        result = await session.execute(select(Role.id).where(Role.id.in_(payload.role_ids)))
        valid_role_ids = set(result.scalars().all())
        for rid in valid_role_ids:
            session.add(UserRole(user_id=user_id, role_id=rid))
    await session.flush()
    await session.commit()
    return {"user_id": str(user_id), "role_ids": [str(r) for r in payload.role_ids]}


@router.get("/{user_id}/roles", response_model=List[RoleRead])
async def get_user_roles(user_id: UUID, session: AsyncSession = Depends(get_session), current_user: UserAccount = Depends(get_current_user)):
    result = await session.execute(
        select(Role).join(UserRole, UserRole.role_id == Role.id).where(UserRole.user_id == user_id)
    )
    roles = result.scalars().all()
    return [RoleRead(id=r.id, code=r.code, name=r.name, description=r.description, enabled=r.enabled) for r in roles]
@router.patch("/{user_id}", response_model=UserRead)
async def update_user(user_id: UUID, payload: UserUpdate, session: AsyncSession = Depends(get_session), current_user: UserAccount = Depends(get_current_user)):
    result = await session.execute(select(UserAccount).where(UserAccount.id == user_id))
    user = result.scalar_one_or_none()
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    if payload.full_name is not None:
        user.full_name = payload.full_name
    if payload.email is not None:
        user.email = payload.email
    if payload.enabled is not None:
        user.enabled = payload.enabled
    await session.flush()
    await session.refresh(user)
    await session.commit()
    return UserRead(id=user.id, username=user.username, full_name=user.full_name, email=user.email, enabled=user.enabled)


@router.delete("/{user_id}")
async def delete_user(user_id: UUID, session: AsyncSession = Depends(get_session), current_user: UserAccount = Depends(get_current_user)):
    result = await session.execute(select(UserAccount).where(UserAccount.id == user_id))
    user = result.scalar_one_or_none()
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    await session.delete(user)
    await session.commit()
    return {"deleted": True, "user_id": str(user_id)}
